import { Context, h, Schema } from 'koishi';
import { readFileSync, existsSync } from 'fs'
import { resolve } from 'path'

const pkg = JSON.parse(
  readFileSync(resolve(__dirname, '../package.json'), 'utf-8')
)

export const name = 'one-or-two';

export const usage = `
<h1>🎲 Koishi 插件: 随机二选一 ${name} 🎲</h1>
<h2>🎯 插件版本：v${pkg.version}</h2>
<p>
  💬 插件使用问题 / 🐛 Bug反馈 / 👨‍💻 插件开发交流，欢迎加入QQ群：<b>259248174</b> 🎉
</p>

<hr>

<h3>💡 使用指南</h3>
<p>当消息中包含“还是”或“or”时，插件会随机选择一个选项并回复，并有小概率回复“or”本身。</p>
<ul>
  <li><b>示例 1：</b>
    <ul>
      <li>用户发送: <code>A还是B？</code></li>
      <li>机器人回复: <code>A！</code> 或 <code>B！</code> 或 <code>还是！</code></li>
    </ul>
  </li>
  <li><b>示例 2：</b>
    <ul>
      <li>用户发送: <code>one or two?</code></li>
      <li>机器人回复: <code>one！</code> 或 <code>two！</code> 或 <code>or！</code></li>
    </ul>
  </li>
</ul>

<hr>

<h3>⚙️ 配置说明</h3>
<p>本插件支持以下配置项：</p>
<ul>
  <li><b><code>orWord</code></b>:
    <p>类型: <code>string[]</code></p>
    <p>描述: 用于分割选项的关键词，默认为 <code>['or', '还是']</code>。</p>
  </li>
  <li><b><code>orProbability</code></b>:
    <p>类型: <code>number</code></p>
    <p>描述: 回复关键词本身的概率，范围 0-1，默认为 <code>0.01</code>。</p>
  </li>
</ul>
`

export interface Config {
  mustContainAtBotSelf: boolean;

  orWord: string[];
  orProbability: number;
  
  verboseConsoleOutput: boolean;
}

export const Config: Schema<Config> = Schema.intersect([
  Schema.object({
    mustContainAtBotSelf: Schema.boolean().default(true).description('是否必须包含 艾特机器人自己的消息 才触发'),

    orWord: Schema.array(String).default(['or', '还是']).role('table').description('默认是 or 和 还是'),
    orProbability: Schema.number().default(0.01).min(0).max(1).step(0.01).description('发送 or 本身的概率'),
  }).description("基础设置"),

  Schema.object({
    verboseConsoleOutput: Schema.boolean().default(false).description('是否在控制台输出详细日志'),
  }).description("调试设置")
]) 


export function apply(ctx: Context, config: Config) {
  ctx.on('message', async (session) => {
    let msgContainAtBotSelf = false;
    for ( const e of session.event.message.elements ){
      if ( e.type === 'at' && e.attrs.id === session.bot.selfId ){
        msgContainAtBotSelf = true;
        break;
      }
    }
    if ( config.mustContainAtBotSelf && !msgContainAtBotSelf )
      return;

    if (!session.content) 
      return;

    const elements = h.parse(session.content);
    let payload = [];
    for (const e of elements) {
      if ( e.type!=='text' ) 
        continue;
      payload.push(e);
    }
    let textConcent = h.unescape(payload.join(''));
    if ( textConcent.endsWith('?') || textConcent.endsWith('？') )
      textConcent = textConcent.slice(0, -1);
    
    for (const word of config.orWord) {
      // 使用正则创建分割，并保留分隔符
      const regex = new RegExp(`(\\s*${word}\\s*)`, 'i');
      const parts = textConcent.split(regex);
      /*
      ['吃饭', '还是', '睡觉？']
      ['Do you like cat', ' or ', 'dog?']
      ['A', ' or ', 'B', ' or ', 'C?']
      */
      if ( config.verboseConsoleOutput )
        ctx.logger.info(`parts = ${JSON.stringify(parts)}`);
      
      if (parts.length > 1) {
        const options = parts
          .filter(part => part.trim() !== '') // 过滤空字符串
          .map(part => part.trim()); 
        if ( config.verboseConsoleOutput )
          ctx.logger.info(`options = ${JSON.stringify(options)}`);

        // 1. 决定是否发送 orWord 本身
        if (Math.random() < config.orProbability) {
          await session.send(word + ' !');
          return;
        }

        // 2. 如果没有发送 orWord，则其他的非orWord部分中选择
        const nonOrOptions = options
          .filter(part => part.toLowerCase().trim() !== word.toLowerCase().trim());
        
        if (nonOrOptions.length <= 0) 
          return;

        const randomIndex = Math.floor(Math.random() * nonOrOptions.length);
        let selected = nonOrOptions[randomIndex].trim();

        await session.send(selected + '！');
        return;
      }
    }

  });

}